The approaches described in this section are approaches that could be pursued, but not necessarily approaches that have been previously conceived or pursued. Therefore, unless otherwise indicated, it should not be assumed that any of the approaches described in this section qualify as prior art merely by virtue of their inclusion in this section.
Programming languages such as Sun Microsystem's Java® programming language allow programmers to develop applications in one language for many platforms with relative ease, allowing more resources to be spent on the development of a product rather than ensuring interoperability.
In a typical Java implementation, whenever a Java application is executed, an instance of a Java virtual machine (JVM) is also started to support the execution of the Java application. The JVM, which may be in native code, interprets and executes Java bytecodes. Java bytecodes are derived from Java source code, which is created and understood by a human programmer. The bytecodes act as an intermediate level of code. A Java program may by executed on any platform on which a JVM is executing.
Sometimes, it is more desirable to execute Java applications in native machine code rather than having the JVM interpret bytecodes. In such instances, bytecodes can be compiled into native machine code by a compiler, typically referred to as a just-in-time or JIT compiler. By doing so, the JVM enables a particular application to be executed faster (rather than using a Java interpreter to execute the Java bytecodes of the application, the application is executed directly by the processor, which is faster).
The JVM includes a sampling mechanism for triggering the compilation of bytecodes down to native machine code at certain intervals. For instance, a sampling mechanism may be set to trigger compilation every thirty milliseconds. However, compilation consumes system resources that could be used for other purposes. Thus, in order to minimize the effect of compilation, the JVM may set a limit on compilation such that compilation may only occur for five milliseconds at a time, for example. This is especially useful in single processor systems with only enough resources to run one processor thread at a time. By limiting compilation via the sampling mechanism, the JVM guarantees that compilation will not weigh down system resources by occupying too much time on the processor thread.
One drawback of the sampling mechanism is the static nature of the compilation. Compilation is set to take place at specific times and is limited to a certain duration. However, for processor intensive programs, such as benchmarking applications, it may be desirable to compile as many methods as possible in order to maximize the efficiency of execution. For such instances, in addition to sampling, some virtual machines employ the dynamic compilation of “hot methods” (methods that are invoked frequently within a certain period of time). Hot methods are compiled by tracking a list of recently executed methods. Each method in the list is marked, causing the method to be compiled for native execution instead of interpretive execution.
One of the drawbacks of the dynamic compilation of hot methods, however, is that the compiler can quickly consume a disproportionate amount of system resources. This is especially true if there is a large number of hot methods. This can adversely affect other system functions, such as the rendering of dynamic output such as video or audio. For example, the frames of a video animation may not refresh at a necessary rate if there is not enough processing power, causing a viewer of an animation to perceive an undesirable stutter, pause or blank image.
From the above discussion, it is clear that neither the static sampling approach nor the dynamic compilation of hot methods approach, by themselves, provide wholly satisfactory results. Thus, an improved mechanism for managing compilation is needed.